package com.pay.web.utils;

import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by chenweiyi on 2018/2/5.
 */
public class HttpClientUtils {

    private static final String HTTP = "http";
    private static final String HTTPS = "https";

    private static SSLConnectionSocketFactory sslsf = null;

    private static PoolingHttpClientConnectionManager cm = null;

    private static SSLContextBuilder builder = null;

    static {
        try{
            builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            });
            sslsf = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"},null, NoopHostnameVerifier.INSTANCE);
            Registry<ConnectionSocketFactory> registry =RegistryBuilder.<ConnectionSocketFactory>create()
                    .register(HTTP, new PlainConnectionSocketFactory())
                    .register(HTTPS, sslsf)
                    .build();
            cm = new PoolingHttpClientConnectionManager(registry);
            cm.setMaxTotal(200);
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    public static CloseableHttpClient getHttpClient(){
        CloseableHttpClient client = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .setConnectionManagerShared(true)
                .build();
        return client;
    }

    /**
     * 提交表单请求
     * @param api
     * @param encode
     * @param parameters
     * @return
     */
    public static String postFormRequest(String api,String encode,Map<String,String> parameters){
        CloseableHttpClient client = getHttpClient();
        HttpPost request = new HttpPost(api);
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        for(Map.Entry<String, String> entry : parameters.entrySet()){
            if(entry.getValue() != null){

                BasicNameValuePair pair = new BasicNameValuePair(entry.getKey().replaceAll("([A-Z])", "_$1").toLowerCase(), entry.getValue());
                nameValuePairs.add(pair);
            }
        }
        UrlEncodedFormEntity entity;
        try {
            entity = new UrlEncodedFormEntity(nameValuePairs,encode);
            request.setEntity(entity);
            CloseableHttpResponse response = client.execute(request);
            try{
                HttpEntity httpEntity = response.getEntity();
                int statusCode = response.getStatusLine().getStatusCode();
                if(HttpStatus.SC_OK == statusCode && entity != null){
                    String content = EntityUtils.toString(httpEntity, encode);
                    return content;
                }else{
                    return parseHttpResponse(response);
                }
            }
            finally{
                response.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            try{
                client.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 提交post的JSON字符串
     * @param api
     * @param encode
     * @param json
     * @return
     */
    public static String postJsonRequest(String api,String encode,String json){

        CloseableHttpClient client = getHttpClient();
        HttpPost request = new HttpPost(api);
        HttpEntity entity = new StringEntity(json,encode);
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(30000)
                .setSocketTimeout(30000)
                .build();
        request.setConfig(config);
        request.setHeader("Content-Type","application/json");
        request.setEntity(entity);
        try{
            CloseableHttpResponse response = client.execute(request);
            try {
                if(HttpStatus.SC_OK == response.getStatusLine().getStatusCode()){
                    return EntityUtils.toString(response.getEntity());
                }else{
                    return parseHttpResponse(response);
                }
            }finally {
                response.close();
            }

        } catch(Exception e){
            e.printStackTrace();
        }
        finally {
            request.releaseConnection();
            try{
                client.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String parseHttpResponse(HttpResponse response) throws Exception{

        StringBuilder builder = new StringBuilder();

        HttpEntity entity = response.getEntity();
        builder.append("status:" + response.getStatusLine())
                .append("headers:");
        HeaderIterator iterator = response.headerIterator();
        while(iterator.hasNext()){
            builder.append("\t"+iterator.next());
        }
        if(entity != null){
            String result = EntityUtils.toString(entity);
            builder.append("response length:" + result.length());
            builder.append("response content:" + result);
        }
        return builder.toString();

    }

    public static void main(String [] args){
        String api = "http://127.0.0.1:8080/intetex-mobile/rest/login/login";
        Map<String,String> parameters = new HashMap<String,String>();
        parameters.put("interFaceType","1");
        parameters.put("account","testcompany1");
        parameters.put("password","a123456");
        System.out.println(postFormRequest(api,"UTF-8",parameters));

    }

}
